package dev.blogmoon.cn.system.repository;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import dev.blogmoon.cn.common.utils.StreamUtils;
import dev.blogmoon.cn.system.convert.SysMenuConvert;
import dev.blogmoon.cn.system.entity.SysMenu;
import dev.blogmoon.cn.system.enums.MenuSourceEnum;
import dev.blogmoon.cn.system.module.MenuTreeDTO;
import dev.blogmoon.cn.system.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

@Component
public class SysMenuRepository {

    @Autowired
    private SysMenuService sysMenuService;

    public List<MenuTreeDTO> getMenuTree(MenuSourceEnum menuSource) {
        List<SysMenu> sysMenus = sysMenuService.list(Wrappers.<SysMenu>lambdaQuery().eq(SysMenu::getSource, menuSource.getCode()));
        return convertTreeList(sysMenus);
    }


    public List<MenuTreeDTO> convertTreeList(List<SysMenu> sysMenus) {
        if (CollectionUtils.isEmpty(sysMenus)) {
            return Lists.newArrayList();
        }
        List<MenuTreeDTO> menuTreeDTOS = SysMenuConvert.INSTANCE.toDtoList(sysMenus);
        Map<Long, MenuTreeDTO> menuTreeDTOMap = StreamUtils.getMap(menuTreeDTOS, MenuTreeDTO::getId, e -> e);

        List<MenuTreeDTO> resultList = Lists.newArrayList();
        for (MenuTreeDTO menuTreeDTO : menuTreeDTOS) {
            if (Objects.equals(0L, menuTreeDTO.getParentId()) ||
                    Objects.isNull(menuTreeDTOMap.get(menuTreeDTO.getParentId()))) {
                resultList.add(menuTreeDTO);
                continue;
            }
            MenuTreeDTO parent = menuTreeDTOMap.get(menuTreeDTO.getParentId());
            if (Objects.nonNull(parent)) {
                List<MenuTreeDTO> children = Optional.ofNullable(parent.getChildren()).orElse(Lists.newArrayList());
                children.add(menuTreeDTO);
                parent.setChildren(children);
                children.sort(Comparator.comparing(MenuTreeDTO::getSort));
            }
        }
        resultList.sort(Comparator.comparing(MenuTreeDTO::getSort));
        return resultList;
    }


    public MenuTreeDTO detail(Long id) {
        SysMenu sysMenu = sysMenuService.getById(id);
        return SysMenuConvert.INSTANCE.toDto(sysMenu);
    }

    public void save(MenuTreeDTO menuTreeDTO, MenuSourceEnum sourceEnum) {
        SysMenu sysMenu = SysMenuConvert.INSTANCE.toEntity(menuTreeDTO);
        if (Objects.nonNull(sysMenu.getId())) {
            sysMenu.setModifyField();
            sysMenuService.updateById(sysMenu);
        } else {
            sysMenu.setSource(sourceEnum.getCode());
            sysMenu.setCreateField();
            sysMenuService.save(sysMenu);
        }
    }

    public void removeById(Long id) {
        sysMenuService.removeById(id);
    }
}
